#ifndef E2FS_TYPES_H
#define E2FS_TYPES_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ext2fs/ext2_fs.h>

/* Redefine shorter names for types */
typedef struct ext2_super_block		SUPER;
typedef struct ext2_group_desc		GROUP;
typedef struct ext2_inode			INODE;
typedef struct ext2_dir_entry_2		DIR;

typedef unsigned char		uchar;
typedef unsigned short		ushort;
typedef unsigned int		uint;
typedef unsigned long		ulong;
typedef unsigned long long	u2xlong;

/* Create a bool type for C */
typedef enum boolean
{
	false = 0, true
} bool;

/* Function pointer typedef for commands */
typedef (*command)(char*);

/* Standard values for Ext2 systems */
#define	STD_BLK_SIZE			1024
#define SECTOR_SIZE				512
#define STD_INODES_PER_BLOCK	STD_BLK_SIZE / sizeof(INODE)
#define EXT2_MAGIC				0xEF53
#define EXT2_MAX_FILE_LENGTH	256
#define NUM_DIRECT_BLOCKS		12

/* Define special block numbers for floppy disks */
#define FD_SUPER_BLK			1
#define FD_GROUP_DESC_BLK		2
#define FD_BLK_BITMAP_BLK		3
#define FD_INODE_BITMAP_BLK		4
#define FD_INODE_TABLE_BLK		5

/* Define reserved inode numbers */
#define BAD_BLOCKS_INODE		1
#define ROOT_INODE				2
#define BOOT_LOADER_INODE		5
#define UNDELETE_INODE			6

/* Inode access rights */
#define IACCESS_OTH_EXEC		0x0001
#define IACCESS_OTH_WRITE		0x0002
#define IACCESS_OTH_READ		0x0004

#define IACCESS_GRP_EXEC		0x0008
#define IACCESS_GRP_WRITE		0x0010
#define IACCESS_GRP_READ		0x0020

#define IACCESS_USR_EXEC		0x0040
#define IACCESS_USR_WRITE		0x0080
#define IACCESS_USR_READ		0x0100

/* Inode modes */
#define IMODE_DIRECTORY			0x4000
#define IMODE_REGFILE			0x8000

/* File access */
#define FILE_READ				0x0001
#define FILE_WRITE				0x0002
#define FILE_APPEND				0x0004
#define FILE_READ_WRITE			(FILE_READ | FILE_WRITE)

/* Process status's */
#define PROC_FREE				0
#define PROC_BUSY				1
#define PROC_KILLED				2
#define PROC_READY				3

/* Simulator table sizes */
#define NUM_MEM_INODES			50
#define NUM_MOUNTS				10
#define NUM_PROCS				10
#define NUM_FILE_DESC			10
#define NUM_OPEN_FILE			50

/* Simulator defined values */
#define ROOT_DEVICE				0
#define MAX_PATH_LENGTH			5000
#define MAX_BLOCK_SIZE			8192
#define DEFAULT_FILE_MODE		0x81A4
#define DEFAULT_DIR_MODE		0x41ED

/* Create a type for inode location */
typedef struct loc
{
	int   deviceHandle;
	ulong inodeNum;
} LOC;

/* Ext2/Ext3 Disk Information */
typedef struct ext2disk
{
	ushort	blockSize;
	ushort	inodeSize;
	uint	numInodes;
	uint	numBlocks;
	ushort	inodesPerBlk;
	ushort	groupsPerBlk;
	ushort	numGroups;
	char	name[EXT2_MAX_FILE_LENGTH];
} EXT2_DISK;

/* Mounted Device structure */
typedef struct mount
{
	EXT2_DISK		diskInfo;
	bool			busy;
	int				handle;
	struct minode*	mountedInode;
	char			mountedName[64];
} MOUNT;

/* Inode structure for in-memory inodes */
typedef struct minode
{
	INODE	inode;
	LOC		location;
	ushort	refCount;
	bool	dirty;
	bool	mounted;
	bool	busy;
	MOUNT*	mountedDevice;
	char	name[MAX_PATH_LENGTH];
} MINODE;

/* Open File structure */
typedef struct oft
{
	int		mode;
	ushort	refCount;
	MINODE*	memInode;
	ulong	offset;
} OFT;

/* System process */
typedef struct proc
{
	uint			uid;
	uint			pid;
	uint			gid;
	uint			ppid;
	uint			status;
	MINODE*			cwd;
	OFT*			files[NUM_FILE_DESC];
	struct proc*	next;
	struct proc*	parent;
	struct proc*	child;
	struct proc*	sibling;
} PROC;

#endif
